package com.wty.app.wifilamp.wifi;

import android.util.Log;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;

/**
 * TCP Socket客户端
 */
public abstract class TcpClient implements Runnable {

    private int port;
    private String hostIP;
    private boolean connect = false;
    private SocketTransceiver transceiver;

    /**
     * 建立连接
     * <p>
     * 连接的建立将在新线程中进行
     * <p>
     * 连接建立成功，回调{@code onConnect()}
     * <p>
     * 连接建立失败，回调{@code onConnectFailed()}
     *
     * @param hostIP 服务器主机IP
     * @param port   端口
     */
    public void connect(String hostIP, int port) {
        this.hostIP = hostIP;
        this.port = port;
        new Thread(this).start();
    }

    @Override
    public void run() {
        Socket socket = null;
        try {
            socket = new Socket();
            SocketAddress socketAddress = new InetSocketAddress(hostIP,
                    port);// IP和端口号
            //阻塞等待连接
            socket.connect(socketAddress, 5000);
            transceiver = new SocketTransceiver(socket) {

                @Override
                public void onReceive(InetAddress addr, String s) {
                    connect = true;
                    TcpClient.this.onReceive(this, s);
                }

                @Override
                public void onDisconnect(InetAddress addr) {
                    connect = false;
                    TcpClient.this.onDisconnect(this);
                }
            };
            transceiver.start();
            connect = true;
            this.onConnect(transceiver);
        } catch (Exception e) {
            e.printStackTrace();
            //关闭socket
            try {
                if(socket != null){
                    socket.close();
                }
            } catch (IOException e1) {
                Log.e("wifilamp", "unable to close() socket during connection failure", e1);
            }
            this.onConnectFailed();
        }
    }

    /**
     * 断开连接
     * <p>
     * 连接断开，回调{@code onDisconnect()}
     */
    public void disconnect() {
        if (transceiver != null) {
            transceiver.stop();
            transceiver = null;
        }
    }

    /**
     * 判断是否连接
     *
     * @return 当前处于连接状态，则返回true
     */
    public boolean isConnected() {
        return connect;
    }

    /**
     * 获取Socket收发器
     *
     * @return 未连接则返回null
     */
    public SocketTransceiver getTransceiver() {
        return isConnected() ? transceiver : null;
    }

    /**
     * 连接建立
     *
     * @param transceiver SocketTransceiver对象
     */
    public abstract void onConnect(SocketTransceiver transceiver);

    /**
     * 连接建立失败
     */
    public abstract void onConnectFailed();

    /**
     * 接收到数据
     * <p>
     * 注意：此回调是在新线程中执行的
     *
     * @param transceiver SocketTransceiver对象
     * @param s           字符串
     */
    public abstract void onReceive(SocketTransceiver transceiver, String s);

    /**
     * 连接断开
     * <p>
     * 注意：此回调是在新线程中执行的
     *
     * @param transceiver SocketTransceiver对象
     */
    public abstract void onDisconnect(SocketTransceiver transceiver);
}